/**
 * Created on 2007-03.09 01:02
 */
package game;

import game.input.Control;
import game.input.InputManager;

import java.awt.Color;
import java.util.ArrayList;
import java.util.Iterator;

import game.score.ScoreManager;
import manager.Manager;
import game.media.MediaManager;
import game.media.audio.Sound;
import game.media.gfx.EntityManager;
import game.media.gfx.RenderManager;
import game.media.gfx.SquareEntity;
import game.media.gfx.TextEntity;

/**
 * @author David Wallin
 * 
 * A class keeping track of all active blocks (3 at time that is)
 * The update(int deltaTime) method must be called every frame, with
 * an accurate deltaTime on this manager
 * 
 * This is in fact the game in itself
 */
public class BlockManager extends Manager
{
	/**
	 * The minimum distance between two blocks.
	 */
	private final int						MINIMUM_DISTANCE_BETWEEN_BLOCKS = 4;
	
	/**
	 * The spawn x coordinate of a new piece on the screen
	 */
	private final int						SPAWN_X = 5;
	/**
	 * The spawn y coordinate of a new piece on the screen
	 */
	private final int						SPAWN_Y = 2;
	/**
	 * The x coordinate of the next piece, as it is previewed on the screen
	 */
	private final int						PREVIEW_X = 2;
	/**
	 * The y coordinate of the next piece, as it is previewed on the screen
	 */
	private final int						PREVIEW_Y = 2;
	
	/**
	 * The matris in which the game takes place
	 */
	private Matris							m_GameArea;
	/**
	 * The matris showing info
	 */
	private Matris							m_InfoArea;
	
	/**
	 * The lower block on the screen (if there is only one block on screen, this is it!)
	 */
	private Block							m_LowerBlock;
	/**
	 * The middle block on the screen (if there are two blocks or more on screen, the second from down is this)
	 */
	private Block							m_MiddleBlock;
	/**
	 * The upper block on the screen, if there are three blocks currently on screen
	 */
	private Block							m_UpperBlock;
	/**
	 * Coming attractions :) an array of coming blocks
	 */
	private ArrayList<Block>				m_NextBlocks;
	/**
	 * All the old blocks, but split into components, or squares, so we know what the game area looks like
	 */
	private ArrayList<BlockComponent>		m_OldBlocks;
	
	/**
	 * The control controlling the lower piece
	 */
	private Control							m_LowerControl;
	/**
	 * The control controlling the middle piece
	 */
	private Control							m_MiddleControl;
	/**
	 * The control controlling the upper piece
	 */
	private Control							m_UpperControl;
	/**
	 * The control controlling the preview piece
	 */
	private Control							m_PreviewControl;
	
	/**
	 * Status of the game in apsect to being paused or not
	 */
	private boolean							m_Paused;
	/**
	 * Timer keeping track of the time passed since the last time the blocks were moved down
	 */
	private int								m_Timer;
	/**
	 * The current interval between blocks moving down (unit is milliseconds)
	 */
	private int								m_BlockDropInterval;
	/**
	 * This will be true when the game is ending
	 */
	private boolean							m_GameOver;
	
	/**
	 * A text entity displaying the current score
	 */
	private TextEntity						m_ScoreEntity;
	/**
	 * A text entity displaying the current level
	 */
	private TextEntity						m_LevelEntity;
	/**
	 * A text entity displaying the current number of lines removed
	 */
	private TextEntity						m_LinesEntity;
	/**
	 * A text entity displaying the highest score taken by any player
	 */
	private TextEntity						m_TopScoreEntity;
	/**
	 * A text entity displaying what to do to start/unpause the game
	 */
	private TextEntity						m_PressToStartEntity;
	/**
	 * A text entity displaying the text "GAME PAUSED"
	 */
	private TextEntity						m_IsPausedEntity;
	/**
	 * A text entity displaying the text "NEXT BLOCK"
	 */
	private TextEntity						m_NextBlockEntity;
	
	/*
	 * help text stuff (full help)
	 */
	
	/**
	 * A text entity displaying help for the controls (spin in the preview window)
	 */
	private TextEntity						m_HelpSpinPreview;
	/**
	 * A text entity displaying help for the controls (spin in play field)
	 */
	private TextEntity						m_SpinBlockFullHelp;
	/**
	 * A text entity displaying help for the controls (pull down a block)
	 */
	private TextEntity						m_PullBlockFullHelp;
	/**
	 * A text entity displaying help for the controls (move lower block left)
	 */
	private TextEntity						m_LowerLeftFullHelp;
	/**
	 * A text entity displaying help for the controls (move lower block right)
	 */
	private TextEntity						m_LowerRightFullHelp;
	/**
	 * A text entity displaying help for the controls (move middle block left)
	 */
	private TextEntity						m_MiddleLeftFullHelp;
	/**
	 * A text entity displaying help for the controls (move middle block right)
	 */
	private TextEntity						m_MiddleRightFullHelp;
	/**
	 * A text entity displaying help for the controls (move upper block left)
	 */
	private TextEntity						m_UpperLeftFullHelp;
	/**
	 * A text entity displaying help for the controls (move upper block right)
	 */
	private TextEntity						m_UpperRightFullHelp;
	
	/*
	 * help text stuff (short help)
	 */
	
	/**
	 * A text entity displaying short help for the controls (spin in play field)
	 */
	private TextEntity						m_SpinBlockShortHelp;
	/**
	 * A text entity displaying short help for the controls (pull down a block)
	 */
	private TextEntity						m_PullBlockShortHelp;
	/**
	 * A text entity displaying short help for the controls (move lower block left)
	 */
	private TextEntity						m_LowerLeftShortHelp;
	/**
	 * A text entity displaying short help for the controls (move lower block right)
	 */
	private TextEntity						m_LowerRightShortHelp;
	/**
	 * A text entity displaying short help for the controls (move middle block left)
	 */
	private TextEntity						m_MiddleLeftShortHelp;
	/**
	 * A text entity displaying short help for the controls (move middle block right)
	 */
	private TextEntity						m_MiddleRightShortHelp;
	/**
	 * A text entity displaying short help for the controls (move upper block left)
	 */
	private TextEntity						m_UpperLeftShortHelp;
	/**
	 * A text entity displaying short help for the controls (move upper block right)
	 */
	private TextEntity						m_UpperRightShortHelp;
	
	/*
	 * help text stuff
	 */
	
	private boolean							m_DisplayFullHelpSpinBlock;
	private boolean							m_DisplayFullHelpPullBlock;
	private boolean							m_DisplayFullHelpUpperLeft;
	private boolean							m_DisplayFullHelpUpperRight;
	private boolean							m_DisplayFullHelpMiddleLeft;
	private boolean							m_DisplayFullHelpMiddleRight;
	private boolean							m_DisplayFullHelpLowerLeft;
	private boolean							m_DisplayFullHelpLowerRight;
	
	/**
	 * The one instance of the shape manager
	 */
	private ShapeManager					m_ShapeManager = ShapeManager.INSTANCE;
	/**
	 * The one instance of the score manager
	 */
	private ScoreManager					m_ScoreManager = ScoreManager.INSTANCE;
	/**
	 * The one instance of the entity manager
	 */
	private EntityManager					m_EntityManager = EntityManager.INSTANCE;
	/**
	 * The one instance of the input manager
	 */
	private InputManager					m_InputManager = InputManager.INSTANCE;
	/**
	 * The one instance of the render manager
	 */
	private RenderManager					m_RenderManager = RenderManager.INSTANCE;
	/**
	 * The one instance of the media manager
	 */
	private MediaManager					m_MediaManager = MediaManager.INSTANCE;
	/**
	 * The one instance of the randomizer
	 */
	//private Randomizer						m_Randomizer = Randomizer.INSTANCE;
	/**
	 * The one instance of the settings class
	 */
	private Settings						m_Settings = Settings.INSTANCE;
	/**
	 * The sound to be played when one or more lines are removed
	 */
	private Sound							m_RemoveLineSound;
	/**
	 * The sound to be played when the maximum number of lines are removed
	 */
	private Sound							m_RemoveLineSpecialSound;
	/**
	 * The sound to be played when the player pauses the game
	 */
	private Sound							m_PauseSound;
	/**
	 * The sound to be played when the player unpauses the game (or starts the game)
	 */
	private Sound							m_UnpauseSound;
	
	public void pressPause(boolean paused)
	{
		m_Paused = paused;
		setStartKeyName();
		
		if(paused)
		{
			m_PauseSound.play(false);
			m_PauseSound.play(true);
			//make sure these entities are drawn last, so they end up on top of all other entities
			m_EntityManager.removeEntity(m_IsPausedEntity);
			m_EntityManager.removeEntity(m_PressToStartEntity);
			m_EntityManager.addEntity(m_IsPausedEntity);
			m_EntityManager.addEntity(m_PressToStartEntity);
		}
		else
		{
			m_UnpauseSound.play(false);
			m_UnpauseSound.play(true);
		}
		
		//hide, or show, depending on the state of the pause button
		m_IsPausedEntity.display(paused);
		m_PressToStartEntity.display(paused);
	}
	
	private void setStartKeyName()
	{
		m_PressToStartEntity.setDynamicText(m_InputManager.getStringRepresentation(m_InputManager.getPauseKeyCode()));
	}
	
	/**
	 * When a block has landed, it is set to null. This method checks if there are any null blocks,
	 * and if so, deal with it properly through setting the correct controls to corresponding blocks.
	 */
	private void checkBlocks()
	{
		boolean blocksChanged = false;
		boolean newMiddleBlockSet = false;
		
		if(m_UpperBlock == null)
		{
			m_UpperControl.setBlock(null);
			blocksChanged = true;
			spawnNewUpperBlock();
		}
		
		if(m_MiddleBlock == null)
		{
			m_MiddleBlock = m_UpperBlock;
			
			if(m_MiddleBlock != null)
			{
				m_MiddleControl.setBlock(m_MiddleBlock);
				m_PreviewControl.setBlock(null);
				newMiddleBlockSet = true;
			}
			
			m_UpperControl.setBlock(null);
			blocksChanged = true;
			spawnNewUpperBlock();
		}
		
		if(m_LowerBlock == null)
		{
			m_LowerBlock = m_MiddleBlock;
			
			if(m_LowerBlock != null)
			{
				m_LowerControl.setBlock(m_LowerBlock);
			}
			else
			{
				//the game has not yet started..
			}
			
			m_MiddleBlock = m_UpperBlock;
			
			if(m_MiddleBlock != null)
			{
				m_MiddleControl.setBlock(m_MiddleBlock);
				m_PreviewControl.setBlock(null);
				newMiddleBlockSet = true;
			}
			else
			{
				m_MiddleControl.setBlock(null);
				queueBlocks();
			}
			
			m_UpperControl.setBlock(null);
			blocksChanged = true;
			spawnNewUpperBlock();
		}
		
		if(blocksChanged)
		{
			if(m_LowerBlock != null)
			{
				m_LowerBlock.setState(BlockComponent.States.NORMAL);
			}
			
			if(m_MiddleBlock != null)
			{
				m_MiddleBlock.setState(BlockComponent.States.HIGHLIGHTED);
				m_NextBlocks.get(0).setState(BlockComponent.States.NORMAL);
			}
			
			if(m_UpperBlock != null)
			{
				m_UpperBlock.setState(BlockComponent.States.NORMAL);
			}
			
			if(newMiddleBlockSet && (m_Settings.getDifficulty() == Settings.DifficultyLevels.HARD))
			{
				m_Settings.setReversedFlip(!m_Settings.getReversedFlip());
			}
		}
	}
	
	/**
	 * Checks if a new block is supposed to be spawned, and in that case, spawns it.
	 * Also checks to see if the game is over.
	 */
	private void spawnNewUpperBlock()
	{
		if(!m_Paused)
		{
			Block currentlyTopmostBlock = m_UpperBlock;
			Block gameOverBlock = null;
			
			if(currentlyTopmostBlock == null)
			{
				currentlyTopmostBlock = m_MiddleBlock;
			}
			
			if(currentlyTopmostBlock == null)
			{
				currentlyTopmostBlock = m_LowerBlock;
			}
			
			if(!m_GameOver)
			{
				if(currentlyTopmostBlock == null)
				{
					//ok, there's only room for one new block, and this is close to the end..
					//let's put this one block on the screen, and check if there's room for it
					m_LowerBlock = getNextBlock();
					
					if(!m_GameArea.checkSpace(SPAWN_X, SPAWN_Y, m_LowerBlock.getBlockShape()))
					{
						//aha!! there's no room for this block
						//that means the game is OVER!!
						
						gameOverBlock = m_LowerBlock;
					}
					else
					{
						//ok, we're good to go
						m_LowerBlock.setPosition(SPAWN_X, SPAWN_Y);
						m_LowerControl.setBlock(m_LowerBlock);
					}
					
					queueBlocks();
				}
				else
				{
					//ok, there's at least one block on the screen
					//that means we get the luxury of space between blocks
					//let's see if there's enough space between this coming block and the one on screen
					if((currentlyTopmostBlock.getMatrisYpos() - (m_NextBlocks.get(0).getHeight() + SPAWN_Y)) > MINIMUM_DISTANCE_BETWEEN_BLOCKS)
					{
						m_UpperBlock = getNextBlock();
						
						if(!m_GameArea.checkSpace(SPAWN_X, SPAWN_Y, m_UpperBlock.getBlockShape()))
						{
							//aha!! there's no room for this block
							//that means the game is OVER!!
							gameOverBlock = m_UpperBlock;
						}
						else
						{
							//ok, we're good to go
							m_UpperBlock.setPosition(SPAWN_X, SPAWN_Y);
							m_UpperControl.setBlock(m_UpperBlock);
						}
						
						queueBlocks();
					}
					else
					{
						m_UpperBlock = null;
					}
				}
			}
			
			if(gameOverBlock != null)
			{
				//ok, weve determined that the game is over.. deal with it appropriately
				MediaManager.INSTANCE.getAudioClip(MediaManager.SOUND_GAME_OVER).play(false);
				MediaManager.INSTANCE.getAudioClip(MediaManager.SOUND_GAME_OVER).play(true);
				//m_Settings.setHelpTextsOn(false);
				
				if(!m_GameOver)
				{
					m_GameOver = true;
					gameOverBlock.setMatrisXpos(SPAWN_X);
					gameOverBlock.setMatrisYpos(SPAWN_Y);
				}
			}
			else
			{
				if(m_GameOver)
				{
					m_GameOver = false;
					InputManager.INSTANCE.forceGameOver();
				}
			}
		}
	}
	
	private void queueBlocks()
	{
		while(m_NextBlocks.size() < 3)
		{
			BasicMatris nextShape = m_ShapeManager.getNextShape();
			//m_NextBlocks.add(new Block(PREVIEW_X, PREVIEW_Y, m_ShapeManager.getNextShape(), getNextColor(), m_InfoArea, this));
			m_NextBlocks.add(new Block(PREVIEW_X, PREVIEW_Y, nextShape, nextShape.getColor(), m_InfoArea, this));
		}
		
		Block previewBlock = m_NextBlocks.get(0);
		previewBlock.display(true);
		
		if(m_MiddleBlock == null)
		{
			m_PreviewControl.setBlock(previewBlock);
			previewBlock.setState(BlockComponent.States.HIGHLIGHTED);
		}
	}
	
	private Block getNextBlock()
	{
		Block nextBlock = null;
		
		if(m_NextBlocks.size() < 2)
		{
			queueBlocks();
		}
		
		nextBlock = m_NextBlocks.remove(0);
		nextBlock.setMatris(m_GameArea);
		nextBlock.setMatrisXpos(SPAWN_X);
		nextBlock.setMatrisYpos(SPAWN_Y);
		
		m_PreviewControl.setBlock(null);
		
		queueBlocks();
		
		return nextBlock;
	}
	/**
	 * Sets a block to null, which in turn will cause reactions the next time
	 * checkBlocks() and spawnNewUpperBlock().
	 * 
	 * This also causes the game area to be filled with the pieces (or BlockComponent:s)
	 * making up this block. This MAY cause reactions the next time checkRows() is called
	 * 
	 * @param block the block to invalidate
	 */
	public void setBlockToNull(Block block)
	{
		boolean blockIdentified = false;
		
		if(m_LowerBlock == block)
		{
			m_LowerBlock = null;
			blockIdentified = true;
		}
		
		if(m_MiddleBlock == block)
		{
			m_MiddleBlock.setState(BlockComponent.States.NORMAL);
			m_MiddleBlock = null;
			blockIdentified = true;
		}
		
		if(m_UpperBlock == block)
		{
			m_UpperBlock = null;
			blockIdentified = true;
		}
		
		if(!blockIdentified)
		{
			throw new IllegalArgumentException("Attempted to invalidate an unidentifiable block");
		}
		
		m_GameArea.addShapeToMatrix(block.getMatrisXpos(), block.getMatrisYpos(), block.getBlockShape());
		m_OldBlocks.addAll(block.getBlockComponents());
		int removedLines = checkRows();
		
		if(removedLines > 0)
		{
			if(removedLines == ShapeManager.MAXIMUM_NUMBER_OF_REMOVABLE_LINES)
			{
				m_RemoveLineSpecialSound.play(false);
				m_RemoveLineSpecialSound.play(true);
			}
			else
			{
				m_RemoveLineSound.play(false);
				m_RemoveLineSound.play(true);
			}
			
			m_ScoreManager.registerRemovedLines(removedLines);
			
			m_LevelEntity.setDynamicText(String.valueOf(m_ScoreManager.getLevel()));
			m_TopScoreEntity.setDynamicText(m_ScoreManager.getHighestScore());
			m_LinesEntity.setDynamicText(String.valueOf(m_ScoreManager.getLines()));
		}
	}
	
	/**
	 * Checks the rows of pieces of blocks in the game area, to see if there
	 * are any full rows, and in that case removes these.
	 * 
	 * @return the number of lines removed during this call
	 */
	private int checkRows()
	{
		//find lowest full row in the matrix
		//identify involved blocks
		//remove involved parts from involved blocks
		//move all blocks above this down one line
		//start over
		//continue until top of matris is reached
		
		//lowest row is bottom, and so always full, therefore -2
		//top row is top, and so always full, therefore > 0 (as opposed to > -1)
		int width = m_GameArea.getWidth() - 1;
		int upperLimit = 0;
		int fullRowsFound = 0;
		
		for(int y = (m_GameArea.getHeight() - 2); y > upperLimit; y--)
		{
			//if we find a full row, we must increase y one step, so as to not miss a row
			boolean fullRow = true;
			
			for(int x = 1; x < width; x++)
			{
				fullRow &= m_GameArea.getPosition(x, y);
			}
			
			if(fullRow)
			{
				//ok, 'y' is a full row
				//find all block components to remove, and free the space on the line in the matris
				fullRowsFound++;
				ArrayList<BlockComponent> blocksToRemove = new ArrayList<BlockComponent>();
				BlockComponent block = null;
				
				for(int x = 1; x < width; x++)
				{
					m_GameArea.setPosition(x, y, false);
					block = getComponentAt(x, y, m_OldBlocks);
					
					if(block != null)
					{
						blocksToRemove.add(block);
					}
				}
				
				//now remove all those block components
				int blocksToRemoveFound = blocksToRemove.size();
				
				for(int i = 0; i < blocksToRemoveFound; i++)
				{
					blocksToRemove.get(i).remove();
					m_OldBlocks.remove(blocksToRemove.get(i));
				}
				
				//now for moving all blocks above this line one step down
				for(int dropDownY = (y - 1); dropDownY > upperLimit; dropDownY--)
				{
					for(int dropDownX = 1; dropDownX < width; dropDownX++)
					{
						block = getComponentAt(dropDownX, dropDownY, m_OldBlocks);
						
						if(block != null)
						{
							m_GameArea.setPosition(dropDownX, dropDownY, false);
							m_GameArea.setPosition(dropDownX, dropDownY + 1, true);
							block.setMatrisYpos(dropDownY + 1);
						}
					}
				}
				
				//finally increase y so we get to check the new line of blocks at the same y-position we just removed and replaced
				y++;
			}
		}
		
		return fullRowsFound;
	}
	
	/**
	 * Finds a BlockComponent at a certain location
	 * 
	 * @param x the x coordinate within the game area
	 * @param y the y coordinate within the game area
	 * @param blocks the list of BlockComponent:s to look in
	 * @return the block at the location, or null if the specified location does not contain a block
	 */
	private BlockComponent getComponentAt(int x, int y, ArrayList<BlockComponent> blocks)
	{
		BlockComponent component = null;
		Iterator<BlockComponent> it = blocks.iterator();
		BlockComponent block = null;
		
		while(it.hasNext() && (component == null))
		{
			block = it.next();
			
			if((block.getMatrisXpos() == x) && (block.getMatrisYpos() == y))
			{
				component = block;
			}
		}
		
		return component;
	}
	
	/**
	 * Perform the initialization
	 */
	protected void doInitialize()
	{
		m_LowerControl = new Control();
		m_MiddleControl = new Control();
		m_UpperControl = new Control();
		m_PreviewControl = new Control();
		m_NextBlocks = new ArrayList<Block>();
		m_OldBlocks = new ArrayList<BlockComponent>();
		
		InputManager.INSTANCE.setLowerControl(m_LowerControl);
		InputManager.INSTANCE.setMiddleControl(m_MiddleControl);
		InputManager.INSTANCE.setUpperControl(m_UpperControl);
		InputManager.INSTANCE.setPreviewControl(m_PreviewControl);
		
		m_LowerBlock = null;
		m_MiddleBlock = null;
		m_UpperBlock = null;
		
		queueBlocks();
		setStartKeyName();
		
		m_ScoreEntity.display(true);
		m_LevelEntity.display(true);
		m_LinesEntity.display(true);
		m_TopScoreEntity.display(true);
		m_PressToStartEntity.display(true);
		m_IsPausedEntity.display(false);
		m_NextBlockEntity.display(true);
		
		m_TopScoreEntity.setDynamicText(m_ScoreManager.getHighestScore());
		
		m_Timer = 0;
		
		//if(m_Settings.getHelpTextsOn())
		{
			//m_BlockDropInterval = BLOCK_DROP_INTERVAL_DURING_HELP_TEXT;
		}
		//else
		{
			//m_BlockDropInterval = INITIAL_BLOCK_DROP_INTERVAL;
		}
		
		//m_BlockDropInterval = m_Settings.getInitialBlockDropInterval();
		m_BlockDropInterval = m_Settings.getBlockDropInterval();
		m_GameOver = false;
	}
	
	/**
	 * Perform the tearing down
	 */
	protected void doTearDown()
	{
		m_NextBlocks.clear();
		m_OldBlocks.clear();
		
		m_ScoreEntity.display(false);
		m_LevelEntity.display(false);
		m_LinesEntity.display(false);
		m_TopScoreEntity.display(false);
		m_PressToStartEntity.display(false);
		m_IsPausedEntity.display(false);
		m_NextBlockEntity.display(false);
	}
	
	/**
	 * Perform the updating
	 */
	protected void doUpdate(int deltaTime)
	{
		m_Timer += deltaTime;
		int dropY = 0;
		
		if(m_Timer > m_BlockDropInterval)
		{
			m_Timer -= m_BlockDropInterval;
			dropY = 1;
		}
		
		if(m_LowerBlock != null)
		{
			m_LowerBlock.setPosition(m_LowerBlock.getMatrisXpos(), m_LowerBlock.getMatrisYpos() + dropY);
		}
		
		if(m_MiddleBlock != null)
		{
			m_MiddleBlock.setPosition(m_MiddleBlock.getMatrisXpos(), m_MiddleBlock.getMatrisYpos() + dropY);
		}
		
		if(m_UpperBlock != null)
		{
			m_UpperBlock.setPosition(m_UpperBlock.getMatrisXpos(), m_UpperBlock.getMatrisYpos() + dropY);
		}
		
		if(m_NextBlocks.size() > 0)
		{
			m_NextBlocks.get(0).setPosition(m_NextBlocks.get(0).getMatrisXpos(), m_NextBlocks.get(0).getMatrisYpos());
		}
		
		//if(!m_Settings.getHelpTextsOn())
		{
			//m_BlockDropInterval = INITIAL_BLOCK_DROP_INTERVAL - (m_ScoreManager.getLevel() * 50);
			m_BlockDropInterval = m_Settings.getBlockDropInterval();
		}
		
		m_ScoreEntity.setDynamicText(String.valueOf(m_ScoreManager.getCurrentlyDisplayedScore()));
		checkBlocks();
		
		/*
		 * Help texts
		 */
		//if(m_Settings.getHelpTextsOn())
		if(m_Settings.getDifficulty() == Settings.DifficultyLevels.EASY)
		{
			if(m_PreviewControl.getBlock() != null)
			{
				//display "spin preview piece" help
				m_EntityManager.removeEntity(m_HelpSpinPreview);
				m_EntityManager.addEntity(m_HelpSpinPreview);
				m_HelpSpinPreview.setXpos(m_InfoArea.getInnerXpos());
				m_HelpSpinPreview.setYpos(m_InfoArea.getInnerY2() - 30);
				//m_HelpSpinPreview.setColor(m_PreviewControl.getBlock().getColor());
				m_HelpSpinPreview.display(true);
			}
			else
			{
				m_HelpSpinPreview.display(false);
			}
			
			if(m_UpperControl.getBlock() != null)
			{
				//display "move upper block" left help
				if(m_DisplayFullHelpUpperLeft)
				{
					m_EntityManager.removeEntity(m_UpperLeftFullHelp);
					m_EntityManager.addEntity(m_UpperLeftFullHelp);
					m_UpperLeftFullHelp.setXpos(m_UpperControl.getBlock().getXpos());
					m_UpperLeftFullHelp.setYpos(m_UpperControl.getBlock().getYpos());
					//m_UpperLeftFullHelp.setColor(m_UpperControl.getBlock().getColor());
					m_DisplayFullHelpUpperLeft = !m_UpperControl.getLeftHasBeenPressedAtLeast_N_Times();
					m_UpperLeftFullHelp.display(m_DisplayFullHelpUpperLeft);
				}
				else
				{
					m_EntityManager.removeEntity(m_UpperLeftShortHelp);
					m_EntityManager.addEntity(m_UpperLeftShortHelp);
					m_UpperLeftShortHelp.setXpos(m_UpperControl.getBlock().getXpos());
					m_UpperLeftShortHelp.setYpos(m_UpperControl.getBlock().getYpos());
					//m_UpperLeftFullHelp.setColor(m_UpperControl.getBlock().getColor());
					m_UpperLeftShortHelp.display(true);
				}
				
				//display "move upper block right" help
				if(m_DisplayFullHelpUpperRight)
				{
					m_EntityManager.removeEntity(m_UpperRightFullHelp);
					m_EntityManager.addEntity(m_UpperRightFullHelp);
					m_UpperRightFullHelp.setXpos(m_UpperControl.getBlock().getXpos() + (m_UpperControl.getBlock().getWidth() * m_RenderManager.getSquareEntityWidth()));
					m_UpperRightFullHelp.setYpos(m_UpperControl.getBlock().getYpos());
					//m_UpperRightFullHelp.setColor(m_UpperControl.getBlock().getColor());
					m_DisplayFullHelpUpperRight = !m_UpperControl.getRightHasBeenPressedAtLeast_N_Times();
					m_UpperRightFullHelp.display(m_DisplayFullHelpUpperRight);
				}
				else
				{
					m_EntityManager.removeEntity(m_UpperRightShortHelp);
					m_EntityManager.addEntity(m_UpperRightShortHelp);
					m_UpperRightShortHelp.setXpos(m_UpperControl.getBlock().getXpos() + (m_UpperControl.getBlock().getWidth() * m_RenderManager.getSquareEntityWidth()));
					m_UpperRightShortHelp.setYpos(m_UpperControl.getBlock().getYpos());
					//m_UpperRightFullHelp.setColor(m_UpperControl.getBlock().getColor());
					m_UpperRightShortHelp.display(true);
				}
			}
			else
			{
				m_UpperLeftFullHelp.display(false);
				m_UpperRightFullHelp.display(false);
				m_UpperLeftShortHelp.display(false);
				m_UpperRightShortHelp.display(false);
			}
			
			if(m_MiddleControl.getBlock() != null)
			{
				//display "move middle block left" help
				if(m_DisplayFullHelpMiddleLeft)
				{
					m_EntityManager.removeEntity(m_MiddleLeftFullHelp);
					m_EntityManager.addEntity(m_MiddleLeftFullHelp);
					m_MiddleLeftFullHelp.setXpos(m_MiddleControl.getBlock().getXpos());
					m_MiddleLeftFullHelp.setYpos(m_MiddleControl.getBlock().getYpos());
					//m_MiddleLeftFullHelp.setColor(m_MiddleControl.getBlock().getColor());
					m_DisplayFullHelpMiddleLeft = !m_MiddleControl.getLeftHasBeenPressedAtLeast_N_Times();
					m_MiddleLeftFullHelp.display(m_DisplayFullHelpMiddleLeft);
				}
				else
				{
					m_EntityManager.removeEntity(m_MiddleLeftShortHelp);
					m_EntityManager.addEntity(m_MiddleLeftShortHelp);
					m_MiddleLeftShortHelp.setXpos(m_MiddleControl.getBlock().getXpos());
					m_MiddleLeftShortHelp.setYpos(m_MiddleControl.getBlock().getYpos());
					//m_MiddleLeftFullHelp.setColor(m_MiddleControl.getBlock().getColor());
					m_MiddleLeftShortHelp.display(true);
				}
				//display "move middle block right" help
				if(m_DisplayFullHelpMiddleRight)
				{
					m_EntityManager.removeEntity(m_MiddleRightFullHelp);
					m_EntityManager.addEntity(m_MiddleRightFullHelp);
					m_MiddleRightFullHelp.setXpos(m_MiddleControl.getBlock().getXpos() + (m_MiddleControl.getBlock().getWidth() * m_RenderManager.getSquareEntityWidth()));
					m_MiddleRightFullHelp.setYpos(m_MiddleControl.getBlock().getYpos());
					//m_MiddleRightFullHelp.setColor(m_MiddleControl.getBlock().getColor());
					m_DisplayFullHelpMiddleRight = !m_MiddleControl.getRightHasBeenPressedAtLeast_N_Times();
					m_MiddleRightFullHelp.display(m_DisplayFullHelpMiddleRight);
				}
				else
				{
					m_EntityManager.removeEntity(m_MiddleRightShortHelp);
					m_EntityManager.addEntity(m_MiddleRightShortHelp);
					m_MiddleRightShortHelp.setXpos(m_MiddleControl.getBlock().getXpos() + (m_MiddleControl.getBlock().getWidth() * m_RenderManager.getSquareEntityWidth()));
					m_MiddleRightShortHelp.setYpos(m_MiddleControl.getBlock().getYpos());
					//m_MiddleRightFullHelp.setColor(m_MiddleControl.getBlock().getColor());
					m_MiddleRightShortHelp.display(true);
				}
				//display "spin middle block" help
				if(m_DisplayFullHelpSpinBlock)
				{
					m_EntityManager.removeEntity(m_SpinBlockFullHelp);
					m_EntityManager.addEntity(m_SpinBlockFullHelp);
					m_SpinBlockFullHelp.setXpos(m_MiddleControl.getBlock().getXpos() + ((m_MiddleControl.getBlock().getWidth() / 2) * m_RenderManager.getSquareEntityWidth()));
					m_SpinBlockFullHelp.setYpos(m_MiddleControl.getBlock().getYpos() + ((m_MiddleControl.getBlock().getHeight() + 1) * m_RenderManager.getSquareEntityHeight()));
					//m_SpinBlockFullHelp.setColor(m_MiddleControl.getBlock().getColor());
					m_DisplayFullHelpSpinBlock = !m_MiddleControl.getRotateHasBeenPressedAtLeast_N_Times();
					m_SpinBlockFullHelp.display(m_DisplayFullHelpSpinBlock);
				}
				else
				{
					m_EntityManager.removeEntity(m_SpinBlockShortHelp);
					m_EntityManager.addEntity(m_SpinBlockShortHelp);
					m_SpinBlockShortHelp.setXpos(m_MiddleControl.getBlock().getXpos() + ((m_MiddleControl.getBlock().getWidth() / 2) * m_RenderManager.getSquareEntityWidth()));
					m_SpinBlockShortHelp.setYpos(m_MiddleControl.getBlock().getYpos() + ((m_MiddleControl.getBlock().getHeight() + 1) * m_RenderManager.getSquareEntityHeight()));
					//m_SpinBlockFullHelp.setColor(m_MiddleControl.getBlock().getColor());
					m_SpinBlockShortHelp.display(true);
				}
			}
			else
			{
				m_MiddleLeftFullHelp.display(false);
				m_MiddleRightFullHelp.display(false);
				m_SpinBlockFullHelp.display(false);
				m_MiddleLeftShortHelp.display(false);
				m_MiddleRightShortHelp.display(false);
				m_SpinBlockShortHelp.display(false);
			}
			
			if(m_LowerControl.getBlock() != null)
			{
				//display "move lower block left" help
				if(m_DisplayFullHelpLowerLeft)
				{
					m_EntityManager.removeEntity(m_LowerLeftFullHelp);
					m_EntityManager.addEntity(m_LowerLeftFullHelp);
					m_LowerLeftFullHelp.setXpos(m_LowerControl.getBlock().getXpos());
					m_LowerLeftFullHelp.setYpos(m_LowerControl.getBlock().getYpos());
					//m_LowerLeftFullHelp.setColor(m_LowerControl.getBlock().getColor());
					m_DisplayFullHelpLowerLeft = !m_LowerControl.getLeftHasBeenPressedAtLeast_N_Times();
					m_LowerLeftFullHelp.display(m_DisplayFullHelpLowerLeft);
				}
				else
				{
					m_EntityManager.removeEntity(m_LowerLeftShortHelp);
					m_EntityManager.addEntity(m_LowerLeftShortHelp);
					m_LowerLeftShortHelp.setXpos(m_LowerControl.getBlock().getXpos());
					m_LowerLeftShortHelp.setYpos(m_LowerControl.getBlock().getYpos());
					//m_LowerLeftFullHelp.setColor(m_LowerControl.getBlock().getColor());
					m_LowerLeftShortHelp.display(true);
				}
				//display "move lower block right" help
				if(m_DisplayFullHelpLowerRight)
				{
					m_EntityManager.removeEntity(m_LowerRightFullHelp);
					m_EntityManager.addEntity(m_LowerRightFullHelp);
					m_LowerRightFullHelp.setXpos(m_LowerControl.getBlock().getXpos() + (m_LowerControl.getBlock().getWidth() * m_RenderManager.getSquareEntityWidth()));
					m_LowerRightFullHelp.setYpos(m_LowerControl.getBlock().getYpos());
					//m_LowerRightFullHelp.setColor(m_LowerControl.getBlock().getColor());
					m_DisplayFullHelpLowerRight = !m_LowerControl.getRightHasBeenPressedAtLeast_N_Times();
					m_LowerRightFullHelp.display(m_DisplayFullHelpLowerRight);
				}
				else
				{
					m_EntityManager.removeEntity(m_LowerRightShortHelp);
					m_EntityManager.addEntity(m_LowerRightShortHelp);
					m_LowerRightShortHelp.setXpos(m_LowerControl.getBlock().getXpos() + (m_LowerControl.getBlock().getWidth() * m_RenderManager.getSquareEntityWidth()));
					m_LowerRightShortHelp.setYpos(m_LowerControl.getBlock().getYpos());
					//m_LowerRightFullHelp.setColor(m_LowerControl.getBlock().getColor());
					m_LowerRightShortHelp.display(true);
				}
				//display "pull lower block" help
				if(m_DisplayFullHelpPullBlock)
				{
					m_EntityManager.removeEntity(m_PullBlockFullHelp);
					m_EntityManager.addEntity(m_PullBlockFullHelp);
					m_PullBlockFullHelp.setXpos(m_LowerControl.getBlock().getXpos() + ((m_LowerControl.getBlock().getWidth() / 2) * m_RenderManager.getSquareEntityWidth()));
					m_PullBlockFullHelp.setYpos(m_LowerControl.getBlock().getYpos() + ((m_LowerControl.getBlock().getHeight() + 1) * m_RenderManager.getSquareEntityHeight()));
					//m_PullBlockFullHelp.setColor(m_LowerControl.getBlock().getColor());
					m_DisplayFullHelpPullBlock = !m_LowerControl.getDropHasBeenPressedAtLeast_N_Times();
					m_PullBlockFullHelp.display(m_DisplayFullHelpPullBlock);
				}
				else
				{
					m_EntityManager.removeEntity(m_PullBlockShortHelp);
					m_EntityManager.addEntity(m_PullBlockShortHelp);
					m_PullBlockShortHelp.setXpos(m_LowerControl.getBlock().getXpos() + ((m_LowerControl.getBlock().getWidth() / 2) * m_RenderManager.getSquareEntityWidth()));
					m_PullBlockShortHelp.setYpos(m_LowerControl.getBlock().getYpos() + ((m_LowerControl.getBlock().getHeight() + 1) * m_RenderManager.getSquareEntityHeight()));
					//m_PullBlockFullHelp.setColor(m_LowerControl.getBlock().getColor());
					m_PullBlockShortHelp.display(true);
				}
			}
			else
			{
				m_LowerLeftFullHelp.display(false);
				m_LowerRightFullHelp.display(false);
				m_PullBlockFullHelp.display(false);
				m_LowerLeftShortHelp.display(false);
				m_LowerRightShortHelp.display(false);
				m_PullBlockShortHelp.display(false);
			}
			/*
			if(!m_DisplayFullHelpLowerLeft && !m_DisplayFullHelpLowerRight && !m_DisplayFullHelpMiddleLeft &&
			   !m_DisplayFullHelpMiddleRight && ! m_DisplayFullHelpPullBlock && !m_DisplayFullHelpSpinBlock &&
			   !m_DisplayFullHelpUpperLeft && !m_DisplayFullHelpUpperRight)
			{
				m_BlockDropInterval = INITIAL_BLOCK_DROP_INTERVAL;
			}
			*/
		}
	}
	
	/**
	 * Get a random color. Possible values are red, blue and yellow
	 * 
	 * @return the random color
	 */
	/*
	private Color getNextColor()
	{
		Color color = null;
		
		int rand = m_Randomizer.getNextInt(0, 2);
		
		if(rand == 0)
		{
			color = Color.yellow;
		}
		
		if(rand == 1)
		{
			color = Color.red;
		}
		
		if(rand == 2)
		{
			color = Color.blue;
		}
		
		return color;
	}
	*/
	/**
	 * Constructor, initializing members
	 */
	public BlockManager()
	{
		m_GameArea = new Matris(RenderManager.MATRIS_WIDTH, RenderManager.MATRIS_HEIGHT, RenderManager.GAME_AREA_OFFSET, 10);
		m_InfoArea = new Matris(RenderManager.MATRIS_EXTRA_WIDTH, RenderManager.MATRIS_EXTRA_WIDTH, (RenderManager.MATRIS_WIDTH * m_RenderManager.getSquareEntityWidth()) + RenderManager.GAME_AREA_OFFSET, 80);
		
		m_Paused = true;
		
		int bkgndX = m_GameArea.getInnerXpos();
		int bkgndY = m_GameArea.getInnerYpos();
		int bkgndWidth = m_GameArea.getInnerPixelWidth();
		int bkgndHeight = m_GameArea.getInnerPixelHeight();
		
		//draw a gray background over the area where the game is played
		new SquareEntity(bkgndX, bkgndY, bkgndWidth, bkgndHeight, Color.DARK_GRAY, false).display(true);
		//draw a gray background over the area where the next piece is displayed
		new SquareEntity(m_InfoArea.getInnerXpos(), m_InfoArea.getInnerYpos(), m_InfoArea.getInnerPixelWidth(), m_InfoArea.getInnerPixelHeight(), Color.DARK_GRAY, false).display(true);
		
		//TODO make the following fonts, positions, and static texts dynamically changing depending on the applet's size
		m_LinesEntity = new TextEntity("Lines: " + TextEntity.DYNAMIC_TEXT, "0", RenderManager.SERIF_14_ITALIC, Color.yellow, m_GameArea.getInnerXpos() + (m_RenderManager.getSquareEntityWidth() * 4), m_RenderManager.getSquareEntityHeight(), 0, 0, false, TextEntity.Justifications.LEFT_JUSTIFICATION);
		m_LevelEntity = new TextEntity("Level: " + TextEntity.DYNAMIC_TEXT, "0", RenderManager.SERIF_14_ITALIC, Color.red, m_InfoArea.getInnerXpos(), m_InfoArea.getInnerY2() + 20, 0, 0, false, TextEntity.Justifications.LEFT_JUSTIFICATION);
		m_ScoreEntity = new TextEntity("Score: " + TextEntity.DYNAMIC_TEXT, "0", RenderManager.SERIF_14_ITALIC, Color.blue, m_InfoArea.getInnerXpos(), m_InfoArea.getInnerY2() + 40, 0, 0, false, TextEntity.Justifications.LEFT_JUSTIFICATION);
		m_TopScoreEntity = new TextEntity("Top score: " + TextEntity.DYNAMIC_TEXT, ScoreManager.NO_HIGHSCORE_FOUND_STRING, RenderManager.SERIF_14_ITALIC, Color.blue, m_InfoArea.getInnerXpos(), m_InfoArea.getInnerY2() + 60, 0, 0, false, TextEntity.Justifications.LEFT_JUSTIFICATION);
		m_NextBlockEntity = new TextEntity("NEXT BLOCK", "", RenderManager.SERIF_12_BOLD, Color.white, m_InfoArea.getInnerXpos() + (m_RenderManager.getSquareEntityWidth() * 1), m_InfoArea.getInnerYpos() - (m_RenderManager.getSquareEntityHeight() * 1), 0, 0, false, TextEntity.Justifications.LEFT_JUSTIFICATION);
		m_PressToStartEntity = new TextEntity("PRESS " + TextEntity.DYNAMIC_TEXT + " TO PLAY", m_InputManager.getStringRepresentation(m_InputManager.getPauseKeyCode()), RenderManager.SANS_SERIF_18_BOLD, Color.white, RenderManager.GAME_AREA_OFFSET + 10, 100, 0, 0, false, TextEntity.Justifications.LEFT_JUSTIFICATION);
		m_IsPausedEntity = new TextEntity("GAME IS PAUSED", "", RenderManager.SANS_SERIF_18_BOLD, Color.white, RenderManager.GAME_AREA_OFFSET + 60, 70, 0, 0, false, TextEntity.Justifications.LEFT_JUSTIFICATION);
		
		Color helpColor = Color.cyan;
		Color upperHelpColor = Color.magenta;
		Color middleHelpColor = Color.orange;
		Color lowerHelpColor = Color.pink;
		
		m_HelpSpinPreview = new TextEntity(TextEntity.DYNAMIC_TEXT + TextEntity.LINE_FEED + "spins the block in the" + TextEntity.LINE_FEED + "\"NEXT BLOCK\" area", m_InputManager.getStringRepresentation(m_InputManager.getMiddleRotateKeyCode()), RenderManager.SANS_SERIF_10_PLAIN, helpColor, 0, 0, 0, 0, true, TextEntity.Justifications.LEFT_JUSTIFICATION);
		m_SpinBlockFullHelp = new TextEntity(TextEntity.DYNAMIC_TEXT + " spins this block" + (Settings.INSTANCE.getReversedFlip() ? " " : " counter ") + "clockwise", m_InputManager.getStringRepresentation(m_InputManager.getMiddleRotateKeyCode()), RenderManager.SANS_SERIF_10_PLAIN, middleHelpColor, 0, 0, 0, 0, false, TextEntity.Justifications.CENTER_JUSTIFICATION);
		m_PullBlockFullHelp = new TextEntity(TextEntity.DYNAMIC_TEXT + " pulls this block down", m_InputManager.getStringRepresentation(m_InputManager.getLowerDropDownKeyCode()), RenderManager.SANS_SERIF_10_PLAIN, lowerHelpColor, 0, 0, 0, 0, false, TextEntity.Justifications.CENTER_JUSTIFICATION);
		m_LowerLeftFullHelp = new TextEntity(TextEntity.DYNAMIC_TEXT + " moves this block left", m_InputManager.getStringRepresentation(m_InputManager.getLowerLeftKeyCode()), RenderManager.SANS_SERIF_10_PLAIN, lowerHelpColor, 0, 0, 0, 0, false, TextEntity.Justifications.RIGHT_JUSTIFICATION);
		m_LowerRightFullHelp = new TextEntity(TextEntity.DYNAMIC_TEXT + " moves this block right", m_InputManager.getStringRepresentation(m_InputManager.getLowerRightKeyCode()), RenderManager.SANS_SERIF_10_PLAIN, lowerHelpColor, 0, 0, 0, 0, false, TextEntity.Justifications.LEFT_JUSTIFICATION);
		m_MiddleLeftFullHelp = new TextEntity(TextEntity.DYNAMIC_TEXT + " moves this block left", m_InputManager.getStringRepresentation(m_InputManager.getMiddleLeftKeyCode()), RenderManager.SANS_SERIF_10_PLAIN, middleHelpColor, 0, 0, 0, 0, false, TextEntity.Justifications.RIGHT_JUSTIFICATION);
		m_MiddleRightFullHelp = new TextEntity(TextEntity.DYNAMIC_TEXT + " moves this block right", m_InputManager.getStringRepresentation(m_InputManager.getMiddleRightKeyCode()), RenderManager.SANS_SERIF_10_PLAIN, middleHelpColor, 0, 0, 0, 0, false, TextEntity.Justifications.LEFT_JUSTIFICATION);
		m_UpperLeftFullHelp = new TextEntity(TextEntity.DYNAMIC_TEXT + " moves this block left", m_InputManager.getStringRepresentation(m_InputManager.getUpperLeftKeyCode()), RenderManager.SANS_SERIF_10_PLAIN, upperHelpColor, 0, 0, 0, 0, false, TextEntity.Justifications.RIGHT_JUSTIFICATION);
		m_UpperRightFullHelp = new TextEntity(TextEntity.DYNAMIC_TEXT + " moves this block right", m_InputManager.getStringRepresentation(m_InputManager.getUpperRightKeyCode()), RenderManager.SANS_SERIF_10_PLAIN, upperHelpColor, 0, 0, 0, 0, false, TextEntity.Justifications.LEFT_JUSTIFICATION);
		
		m_SpinBlockShortHelp = new TextEntity(TextEntity.DYNAMIC_TEXT, m_InputManager.getStringRepresentation(m_InputManager.getMiddleRotateKeyCode()), RenderManager.SANS_SERIF_10_PLAIN, middleHelpColor, 0, 0, 0, 0, false, TextEntity.Justifications.CENTER_JUSTIFICATION);
		m_PullBlockShortHelp = new TextEntity(TextEntity.DYNAMIC_TEXT, m_InputManager.getStringRepresentation(m_InputManager.getLowerDropDownKeyCode()), RenderManager.SANS_SERIF_10_PLAIN, lowerHelpColor, 0, 0, 0, 0, false, TextEntity.Justifications.CENTER_JUSTIFICATION);
		m_LowerLeftShortHelp = new TextEntity(TextEntity.DYNAMIC_TEXT, m_InputManager.getStringRepresentation(m_InputManager.getLowerLeftKeyCode()), RenderManager.SANS_SERIF_10_PLAIN, lowerHelpColor, 0, 0, 0, 0, false, TextEntity.Justifications.RIGHT_JUSTIFICATION);
		m_LowerRightShortHelp = new TextEntity(TextEntity.DYNAMIC_TEXT, m_InputManager.getStringRepresentation(m_InputManager.getLowerRightKeyCode()), RenderManager.SANS_SERIF_10_PLAIN, lowerHelpColor, 0, 0, 0, 0, false, TextEntity.Justifications.LEFT_JUSTIFICATION);
		m_MiddleLeftShortHelp = new TextEntity(TextEntity.DYNAMIC_TEXT, m_InputManager.getStringRepresentation(m_InputManager.getMiddleLeftKeyCode()), RenderManager.SANS_SERIF_10_PLAIN, middleHelpColor, 0, 0, 0, 0, false, TextEntity.Justifications.RIGHT_JUSTIFICATION);
		m_MiddleRightShortHelp = new TextEntity(TextEntity.DYNAMIC_TEXT, m_InputManager.getStringRepresentation(m_InputManager.getMiddleRightKeyCode()), RenderManager.SANS_SERIF_10_PLAIN, middleHelpColor, 0, 0, 0, 0, false, TextEntity.Justifications.LEFT_JUSTIFICATION);
		m_UpperLeftShortHelp = new TextEntity(TextEntity.DYNAMIC_TEXT, m_InputManager.getStringRepresentation(m_InputManager.getUpperLeftKeyCode()), RenderManager.SANS_SERIF_10_PLAIN, upperHelpColor, 0, 0, 0, 0, false, TextEntity.Justifications.RIGHT_JUSTIFICATION);
		m_UpperRightShortHelp = new TextEntity(TextEntity.DYNAMIC_TEXT, m_InputManager.getStringRepresentation(m_InputManager.getUpperRightKeyCode()), RenderManager.SANS_SERIF_10_PLAIN, upperHelpColor, 0, 0, 0, 0, false, TextEntity.Justifications.LEFT_JUSTIFICATION);
		
		m_DisplayFullHelpSpinBlock = true;
		m_DisplayFullHelpPullBlock = true;
		m_DisplayFullHelpUpperLeft = true;
		m_DisplayFullHelpUpperRight = true;
		m_DisplayFullHelpMiddleLeft = true;
		m_DisplayFullHelpMiddleRight = true;
		m_DisplayFullHelpLowerLeft = true;
		m_DisplayFullHelpLowerRight = true;
		
		m_RemoveLineSound = m_MediaManager.getAudioClip(MediaManager.SOUND_REMOVELINE);
		m_RemoveLineSpecialSound = m_MediaManager.getAudioClip(MediaManager.SOUND_REMOVELINE_SPECIAL);
		m_PauseSound = m_MediaManager.getAudioClip(MediaManager.SOUND_PAUSE);
		m_UnpauseSound = m_MediaManager.getAudioClip(MediaManager.SOUND_UNPAUSE);
	}
}
